package thread.threadpoll;

import org.jetbrains.annotations.NotNull;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.*;
import java.util.function.Consumer;

public class ThreadPoolSubmitTest1 {
    public static void main(String[] args) {
        SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,
                10,
                10,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(3),
                new ThreadFactory() {
                    private volatile int mThreadCount = 0;

                    @Override
                    public Thread newThread(@NotNull Runnable r) {
                        updateThreadCount(true);

                        return new Thread("ThreadPool-Thread-" + mThreadCount) {
                            @Override
                            public void run() {
                                r.run();
                                updateThreadCount(false);
                            }
                        };
                    }

                    synchronized
                    private void updateThreadCount(boolean increase) {
                        if (increase) {
                            mThreadCount++;
                        } else {
                            mThreadCount--;
                        }
                    }

                },
                new ThreadPoolExecutor.DiscardPolicy());

        ArrayList<Future> mFutures = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            final int tmpI = i;
            mFutures.add(threadPoolExecutor.submit(new Callable<String>() {
                @Override
                public String call() {
                    System.out.println(mDateFormat.format(new Date(System.currentTimeMillis())) + " " + Thread.currentThread().getName() + " task " + tmpI + " start");

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();

                        return "fail " + tmpI;
                    }

                    System.out.println(mDateFormat.format(new Date(System.currentTimeMillis())) + " " + Thread.currentThread().getName() + " task " + tmpI + " end");
                    System.out.println();

                    return "succeed " + tmpI;
                }
            }));
        }

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        mFutures.forEach(new Consumer<Future>() {
            @Override
            public void accept(Future future) {
                try {
                    System.out.println("future result = " + future.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
